package net.yambal.air.AirAutoUpdater{
	import flash.desktop.NativeApplication;
	import flash.desktop.Updater;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	
	import mx.controls.Alert;
	import mx.core.Application;
	import mx.core.FlexGlobals;
	import mx.core.IMXMLObject;
	import mx.events.CloseEvent;
	import mx.managers.PopUpManager;
	
	import net.yambal.air.AirAutoUpdater.PopUpProgressBar;
	
	public class AirAutoUpdater extends EventDispatcher implements IMXMLObject{
		
		/** version.xmlがあるURL */
		//public var url:String;
		private var versionLoader:URLLoader;
		private var airLoader:URLLoader;
		private var remoteVersion:String;
		private var airUrl:String;
		private var popup:PopUpProgressBar;

		/////////////// Events ////////////////
		/**
		 * AirファイルのDLのCompleteHandler
		 */
		private function downloadAirFileCompleteHandler(event:Event):void {
			airLoader.removeEventListener(Event.COMPLETE, downloadAirFileCompleteHandler);
			airLoader.removeEventListener(IOErrorEvent.IO_ERROR, downloadAirFileIOErrorHandler);
			
			PopUpManager.removePopUp(popup);
			var airFile:File = File.applicationStorageDirectory.resolvePath("updateFile.air");
			var fs:FileStream = new FileStream();
			fs.open(airFile, FileMode.WRITE);
			fs.writeBytes(airLoader.data);
			fs.close();
			
			var updater:Updater = new Updater();
			updater.update(airFile, remoteVersion);
		}
		
		/**
		 * AirファイルのDLのIOErrorEvent
		 */
		private function downloadAirFileIOErrorHandler(event:IOErrorEvent):void {
			airLoader.removeEventListener(Event.COMPLETE, downloadAirFileCompleteHandler);
			airLoader.removeEventListener(IOErrorEvent.IO_ERROR, downloadAirFileIOErrorHandler);
			
			PopUpManager.removePopUp(popup);
			Alert.show('AirファイルのDLに失敗しました');
		}
		
		/**
		 * アップデートチェックのCompleteHandler
		 */
		private function versionCheckCompleteHandler(event:Event):void {
			versionLoader.removeEventListener(Event.COMPLETE, versionCheckCompleteHandler);
			versionLoader.removeEventListener(IOErrorEvent.IO_ERROR, versionCheckIOErrorHandler);

			var xml:XML = new XML(versionLoader.data);
			remoteVersion = xml.version;
			airUrl = xml.url;
			
			var localVersion:String = this.getAppVersion();
			
			if (remoteVersion != localVersion) {
				Alert.show("新しいバージョンに更新可能です\n" +
					"更新しますか？\n\n" +
					"現在のバージョン: " + localVersion + "\n" +
					"新しいバージョン: " + remoteVersion,
					'確認',
					Alert.YES | Alert.NO, null, confirmHandler);
			}else{
				this.dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		
		/**
		 * アプリのローカル Version を取得する
		 **/
		public function getAppVersion():String{
			var appDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
			var ns:Namespace = appDescriptor.namespace();
			return appDescriptor.ns::versionNumber;
		}
		
		/**
		 * Version XMLの URLを取得する
		 **/
		public function getVersionXMLURL(versionXMLURL:String = null):String{
			if(versionXMLURL != null){
				return versionXMLURL;
			}
			var appDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
			var ns:Namespace = appDescriptor.namespace();
			return appDescriptor.ns::versionXMLUrl;
		}

		/**
		 * アップデートチェックのIOErrorEvent
		 */
		private function versionCheckIOErrorHandler(event:IOErrorEvent):void {
			versionLoader.removeEventListener(Event.COMPLETE, versionCheckCompleteHandler);
			versionLoader.removeEventListener(IOErrorEvent.IO_ERROR, versionCheckIOErrorHandler);
			trace('IOError :' + versionLoader.toString())
			this.dispatchEvent(new Event(Event.COMPLETE));
		}
		
		/**
		 * アップデートを行うかの確認WindowのCloseHandler
		 */
		private function confirmHandler(event:CloseEvent):void {
			if (event.detail == Alert.YES) {
				downloadAirFile();
			}
		}
		
		/////////////// Overload ////////////////
		public function initialized(document:Object, id:String):void {
			//checkUpdate();
		}

		public function checkUpdate(versionXMLURL:String = null):void {
			versionLoader = new URLLoader();
			versionLoader.addEventListener(Event.COMPLETE, versionCheckCompleteHandler);
			versionLoader.addEventListener(IOErrorEvent.IO_ERROR, versionCheckIOErrorHandler);
			var url:String = this.getVersionXMLURL(versionXMLURL);
			trace(url);
			versionLoader.load(new URLRequest(url));
		}
		
		public function cancel():void{
			versionLoader.removeEventListener(Event.COMPLETE, versionCheckCompleteHandler);
			versionLoader.removeEventListener(IOErrorEvent.IO_ERROR, versionCheckIOErrorHandler);
			if(airLoader){
				airLoader.removeEventListener(Event.COMPLETE, downloadAirFileCompleteHandler);
				airLoader.removeEventListener(IOErrorEvent.IO_ERROR, downloadAirFileIOErrorHandler);
			}
		}
		
		/////////////// Methods ////////////////
		/**
		 * airファイルをダウンロードする
		 */
		private function downloadAirFile():void {
			airLoader = new URLLoader();
			airLoader.dataFormat = URLLoaderDataFormat.BINARY;
			airLoader.addEventListener(Event.COMPLETE, downloadAirFileCompleteHandler);
			airLoader.addEventListener(IOErrorEvent.IO_ERROR, downloadAirFileIOErrorHandler);
			airLoader.load(new URLRequest(airUrl));
			
			popup = PopUpProgressBar(PopUpManager.createPopUp(DisplayObject(FlexGlobals.topLevelApplication), PopUpProgressBar, true));
			//popup = PopUpProgressBar(PopUpManager.createPopUp(DisplayObject(Application.application), PopUpProgressBar, true));
			PopUpManager.centerPopUp(popup);
			popup.progress.source = airLoader;
		}
	}
}
